#include <stdio.h>
#include <stdlib.h>
#include "MultiThread.h"

mgc_threadpool_t *task_handle_thp = GW_NULL;
__thread char  buffer[65535];


int setup_udp_server(short int serv_port, int * out_sock) 
{
    int sockfd;
    struct sockaddr_in si_me;
    
    // 创建套接字
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
        perror("socket");
        exit(1);
    }
    
    // 初始化套接字地址结构
    memset((char *) &si_me, 0, sizeof(si_me));
    si_me.sin_family = AF_INET;
    si_me.sin_port = htons(serv_port);
    si_me.sin_addr.s_addr = htonl(INADDR_ANY);
    
    // 绑定套接字到端口
    if (bind(sockfd, (struct sockaddr*)&si_me, sizeof(si_me)) == -1) {
        perror("bind");
        exit(1);
    }
	* out_sock = sockfd;
	
	return SUCCESS;
 } 
	



void *__task_thread_msg_handle(void *args)
{
	if(NULL == args)
	{
        return;
	}

    //TO DO

	free(args);
    return;
}

void * __task_thread_recv_msg(void *args)
{
    short int           msg_len = 0;
    fd_set              fdset;
	fd_set       		recv_fdset;
    short int           recv_port;
    int                 ret_val;
    struct timeval      *p_tv=NULL, tv;
	int                 len = 0;

    void                *p_msg = NULL;

	int  res;
	int  recv_sock;

    struct sockaddr_in si_other;
	
	pthread_detach(pthread_self());
	
    res = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    if (res != 0)
    {
        pthread_exit(0);
     }

    res = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
    if (res != 0)
    {
        pthread_exit(0);
    }

	pthread_setname_np(pthread_self(), "THREAD_RCV");

	recv_port = 20000;
	
    /* setup udp server */
    if (FAILURE == setup_udp_server(recv_port, &recv_sock))
    {
        pthread_exit(0);
    }

    FD_ZERO(&recv_fdset);
    FD_SET(recv_sock, &recv_fdset);
	
	while(1)
	{
    	p_msg = NULL;
		
        fdset = recv_fdset;

        tv.tv_sec  = 5;            /* convert ms into s */
        tv.tv_usec = 0;     /* rest of ms into us */
        p_tv = &tv;

        ret_val = select((recv_sock + 1), &fdset, NULL, NULL, (struct timeval*) p_tv);

        if ((ret_val != -1 ) && (ret_val != 0))
        {

            if (FD_ISSET(recv_sock, &fdset))
            {
                /* receive msg */
                int slen = sizeof(si_other);
                if ((msg_len = recvfrom(recv_sock, buffer, 65535, 0, (struct sockaddr *) &si_other, (socklen_t*)&slen)) == -1) {
                    perror("recvfrom");
                    exit(1);
                }
				/* process msg */
				if(task_handle_thp)
				{	
					p_msg = malloc(msg_len+1);
				    if (NULL == p_msg)
				    {
				        continue;
				    }

					memcpy(p_msg, buffer, msg_len);

                    mgc_threadpool_add_task(task_handle_thp, __task_thread_msg_handle, (void *)p_msg);
                    continue;
                    
					
				}
                
            }
        
        }

		
        
    } /* end of while */

	pthread_exit(0);
}


int main(int argc, char* argv[])
{
    char	thread_name[16];
    memset(thread_name, 0, sizeof(thread_name));
    snprintf(thread_name, sizeof(thread_name),  "%s", "TASK_HDL");
    if(NULL == (task_handle_thp = mgc_threadpool_create(thread_name, 1, 1, 10000000)))
    {
        return FAILURE;
    }

    pthread_t   recv_msg_thread;
    if (0 != pthread_create(&recv_msg_thread, NULL, __task_thread_recv_msg, NULL))
    {
        exit(0);
    }

    mgc_threadpool_destroy(task_handle_thp);

    return SUCCESS;


}